package com.keba.otp.crypto;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.security.SecureRandom;

import org.bouncycastle.crypto.CryptoException;
import org.bouncycastle.crypto.KeyGenerationParameters;
import org.bouncycastle.crypto.engines.DESedeEngine;
import org.bouncycastle.crypto.generators.DESedeKeyGenerator;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.util.encoders.Hex;
/**
 * Kriptalashoz szukseges osztaly
 * @author bejmuller
 *
 */
public  class Crypto {
	
	public Crypto() {
	}
	/**
	 * Kriptalashoz szukseges kulcsot general
	 * @return a generalt kulcs
	 */
	public static byte[] generateKey() {
		SecureRandom sr = new SecureRandom();
		DESedeKeyGenerator keygen = new DESedeKeyGenerator();
		KeyGenerationParameters kgp = new KeyGenerationParameters(sr, 192);
		keygen.init(kgp);
		return keygen.generateKey();
	}
	
	/**
	 * Kriptalast vegez
	 * @param plainText a kriptalni kivant karakterlanc
	 * @param key a kriptalashoz szukseges kulcs
	 * @return a kriptalt karakterlanc
	 */
    public static String performEncrypt(String plainText, byte[] key)
    {	
    	ByteArrayOutputStream out = new ByteArrayOutputStream();
    	PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
			new CBCBlockCipher(new DESedeEngine()));
        cipher.init(true, new KeyParameter(key));
        
        byte[] inBytes = plainText.getBytes();

        int inBytesSize = inBytes.length;
        int outBytesSize = cipher.getOutputSize(inBytesSize);
        
        byte[] outBytes = new byte[outBytesSize];
        
        String ret = null;
        int outL;
        outL = cipher.processBytes(inBytes, 0, inBytesSize, outBytes, 0);
        byte[] rv = null;
        if (outL > 0)
        {
            
            rv = Hex.encode(outBytes, 0, outL);
            out.write(rv, 0, rv.length);
        }
        try
        {
            outL = cipher.doFinal(outBytes, 0);
            if (outL > 0)
            {
                rv = Hex.encode(outBytes, 0, outL);
                out.write(rv, 0, rv.length);
            }
            ret = out.toString();
        }
        catch (CryptoException ce)
        {

        }
		try {
			out.flush();
	        out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
        return ret;
    }
    /**
     * Dekriptalast vegez
     * @param encryptedText a dekriptalni kivant karakterlanc
     * @param key a kriptalashoz szukseges kulcs
     * @return a dekriptalt karakterlanc
     */
    public static String performDecrypt(String encryptedText,byte[] key)
    {    
    	ByteArrayOutputStream out = new ByteArrayOutputStream();
    	PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(
			new CBCBlockCipher(new DESedeEngine()));
        cipher.init(false, new KeyParameter(key));
        String ret = null;
        int outL;
        byte[] inBytes = null;
        byte[] outBytes = null;
        inBytes = Hex.decode(encryptedText);
        outBytes = new byte[cipher.getOutputSize(inBytes.length)];

        outL = cipher.processBytes(inBytes, 0, inBytes.length, 
                                    outBytes, 0);
        if (outL > 0)
        {
            out.write(outBytes, 0, outL);
        }
        try
        {
            outL = cipher.doFinal(outBytes, 0);
            if (outL > 0)
            {
                out.write(outBytes, 0, outL);
            }
            ret = out.toString();
        }
        catch (CryptoException ce)
        {

        }
		try {
			out.flush();
	        out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
        return ret;
    }

}